home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Technology Seed / ADC Seed CD - July 1999.toast / NSL 1.1 SDK Alpha2 / Sample Code / Test.c < prev   
Encoding:
C/C++ Source or Header  |  1999-05-10  |  18.3 KB  |  650 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        Test.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    Kevin Arnold - based on sample code from Nav services written by Tony Bacigalupi
  7.  
  8.     Copyright:    © 1998 - 1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.     <16>    03-24-99    KA        converting to new headers
  13.     <15>    03-22-99    KA        converting to new data type names (ie NSLxxx) and handle NSLStandardGetURL returning OSStatus
  14.     <14>    02-23-99    KA        added parameter to the NSLGetStandardURL call
  15.     <13>    02-05-99    KA        added async calling to NSL
  16.     <12>    01-12-99    KA        put back reference to NSLStandardGetURL and use new parsing pb call
  17.     <11>    12-15-98    KA        removed reference to NSLStandardGetURL
  18.     <10>    11-05-98    KA        removed reference to NSLStandardURL.h
  19.     <09>    10-20-98    KA        fixed bug in non-fatal error handling
  20.     <08>    10-15-98    KA        added showURLTEField param option
  21.     <06>    10/08/98    KA        added filter proc param to NSLStandardGetURL call
  22.     <05>     8/25/98    KA        we weren't setting done to false in the beginning of TestSyncServicesLookup
  23.     <04>     8/12/98    KA        added cleanup calls to free our NSL made objects
  24.     <03>     7/21/98    KA        added NSLErrorToString calls
  25.     <01>     4/06/98    KA        Initial check-in.
  26.  
  27.     To Do:
  28. */
  29.  
  30. #include "NSL.h"
  31.  
  32.  
  33. #if PROFILE
  34. #include <Profiler.h>
  35. #endif
  36.  
  37. #include <StdIO.h>
  38. #include <string.h>
  39.  
  40. #include <Threads.h>
  41.  
  42. #ifdef __MWERKS__
  43. #include <SIOUX.h>
  44. #endif
  45.  
  46.  
  47. #define kWebServerType        "http"
  48. #define kFTPServerType        "ftp"
  49. #define kAppleShareType        "AFPServer"
  50. #define kLaserWriterType    "LaserWriter"
  51.  
  52. NSLClientRef        gOurClientRef;
  53. char                gErrorString[256];
  54. char                gSolutionString[256];
  55.  
  56. void TestDefaultNeighborhoodLookup( void );
  57. void TestSyncNeighborhoodLookup( NSLNeighborhood neighborhood ); 
  58. void TestSyncServicesLookup( char* service );
  59. void TestAsyncServicesLookup( char* service );
  60. void TestStandardRegisterURL(void);
  61. void TestStandardDeregisterURL(void);
  62. void DoNSLFatalAlert( NSLError theError );
  63. void DoNSLNonFatalAlert( NSLError theError, Boolean* cancelSearch );
  64.  
  65. static char GetPressedKey()
  66. {
  67.     char c;
  68.     char dummy;
  69.     
  70.     scanf("%c%c", &c, &dummy);
  71.     
  72.     return c;
  73. }
  74.  
  75. void DoNSLFatalAlert( NSLError theError )
  76. {
  77.     char    errorString[256];
  78.     char    solutionString[256];
  79.     
  80.     // call this if you don't want to give the user the option of canceling the search
  81.     NSLErrorToString( theError, errorString, solutionString );
  82.     printf( "Fatal error occurred: %ld\r%s\r%s\r", theError.theErr, errorString, solutionString );
  83. }
  84.  
  85. void DoNSLNonFatalAlert( NSLError theError, Boolean* cancelSearch )
  86. {
  87.     char    errorString[256];
  88.     char    solutionString[256];
  89.     char    result;
  90.     
  91.     // call this if the error isn't fatal and the user might want to continue/cancel the search
  92.     NSLErrorToString( theError, errorString, solutionString );
  93.     printf( "Non Fatal error occurred: %ld\r%s\r%s\r", theError.theErr, errorString, solutionString );
  94.     printf( "Press Y to continue or N to cancel" );
  95.  
  96.     result = GetPressedKey();
  97.     
  98.     if ( result == 'y' || result == 'Y' )
  99.         *cancelSearch = false;
  100.     else
  101.         *cancelSearch = true;
  102. }
  103.  
  104.  
  105. void main()
  106. {
  107.     OSStatus                status;
  108.     Boolean                 quit        = false;
  109.     Boolean                    doBanner    = true;
  110.     Ptr                        url;
  111.     NSLDialogOptions        options;
  112. //    NSLEventUPP             eventUPP = NewNSLEventUPP(OurEventHandler);
  113.     
  114.         
  115.     #ifdef __MWERKS__
  116.     SIOUXSettings.asktosaveonclose = 0;
  117.     #endif
  118.  
  119.     #if PROFILE
  120.     ProfilerInit(collectDetailed, bestTimeBase, 500, 20);
  121.     #endif
  122.  
  123.     printf("NSL API Test\rGenerated %s at %s\r\r", __DATE__, __TIME__);
  124.  
  125.     status = NSLOpenNavigationAPI( &gOurClientRef );
  126.     
  127.     if ( status && status != kNSLSomePluginsFailedToLoad )
  128.         printf("NSLAPI could not be opened due to an internal error\r");
  129.     else
  130.     {
  131.         if ( status == kNSLSomePluginsFailedToLoad )
  132.         {
  133.             // this isn't a fatal error, so we want to let someone know but we will continue.
  134.             NSLError    cludgeError;            // we have to crock one as this is the only time we will get back an OSStatus
  135.                                                 // instead of an NSLError.  Just make theContext be zero
  136.             cludgeError.theErr = status;
  137.             cludgeError.theContext = 0;
  138.             
  139.             NSLErrorToString( cludgeError, gErrorString, gSolutionString );
  140.             printf("Error #%ld: %s\r", cludgeError.theErr, gErrorString );
  141.             printf("Solution: %s\r", gSolutionString );
  142.         }
  143.         
  144.         do {
  145.             char c;
  146.             
  147.             if ( doBanner )
  148.                 printf("\r\r\rPlease make a choice [1-6 and hit return]:\r\t1 - Get list of Default Neighborhoods available\r\t2 - Get list of Webservers in a Neighborhood(sync)\r\t3 - Get list of Webservers in a Neighborhood(async)\r\t4 - Get list of AppleShare servers in a Neighborhood\r\t5 - Browse for url\r\t6 - QUIT\r\r> ");
  149.  
  150.             c = GetPressedKey();        
  151.             
  152.             doBanner = true;
  153.             
  154.             switch ( c)
  155.             {
  156.                 case '1':
  157.                     TestDefaultNeighborhoodLookup();
  158.                     break;
  159.                     
  160.                 case '2':
  161.                     TestSyncServicesLookup(kWebServerType);
  162.                     break;
  163.                     
  164.                 case '3':
  165.                     TestAsyncServicesLookup(kWebServerType);
  166.                     break;
  167.                     
  168.                 case '4':
  169.                     TestSyncServicesLookup(kAppleShareType);
  170.                     break;
  171.                     
  172.                 case '5':
  173.                     NSLGetDefaultDialogOptions( &options );
  174.                     
  175.                     status = NSLStandardGetURL( &options, nil, nil, nil, "Web,http,https;FTP,ftp;AppleShare,AFPServer,afp;", &url );
  176.                     
  177.                     if ( status == noErr )
  178.                     {
  179.                         printf( "\rURL Returned: %s\r", url );
  180.                         url = NSLFreeURL( url );
  181.                     }
  182.                     else if ( status == kNSLUserCanceled )
  183.                         printf( "\rUser Canceled URL Selection\r");
  184.                     else
  185.                         printf( "\rNSLStandardGetURL returned: %ld", status );
  186.                     
  187.                     break;
  188.                     
  189.                 case '6':
  190.                     printf("Bye now!\r");
  191.                     quit = true;
  192.                     break;
  193.                 
  194.                 default:
  195.                     doBanner = false;
  196.             }
  197.  
  198.         } while ( quit == false );
  199.     }
  200.     
  201.     #if PROFILE
  202.     ProfilerDump("\pPerformances");
  203.     ProfilerTerm();
  204.     #endif
  205.     
  206.     ExitToShell();
  207. }
  208.  
  209. #define    kBufferLength    4096
  210.  
  211. void TestDefaultNeighborhoodLookup( void )
  212. {
  213.     NSLNeighborhood neighborhood;
  214.     
  215.     printf( "Getting default NSLNeighborhoods\r\r" );
  216.     
  217.     neighborhood = NSLMakeNewNeighborhood( "", NULL );        // empty string for default neighborhood lookup, NULL for empty protocol string 
  218.                                                             // meaning we want all default neighborhoods
  219.     TestSyncNeighborhoodLookup( neighborhood );
  220.  
  221.     NSLFreeNeighborhood( neighborhood );                    // make sure we free up this memory
  222. }
  223.  
  224.  
  225.  
  226. void TestSyncNeighborhoodLookup( NSLNeighborhood neighborhood )
  227. {
  228.     char                tempName[256];
  229.     long                bufLen = kBufferLength;
  230.     char*                buffer = NULL;
  231.     char*                tempPtr = NULL;
  232.     NSLRequestRef        ourRequestRef;
  233.     NSLClientAsyncInfoPtr    ourAsyncInfo;
  234.     NSLError            iErr = kNSLErrorNoErr;
  235.     NSLNeighborhood        nhPtr = NULL;
  236.     long                nhLength, tempPtrLength;
  237.     Boolean                done = false;
  238.     
  239.     printf( "Looking up Neighborhoods\r\r" );
  240.     
  241.     buffer = NewPtr( bufLen );
  242.     
  243.     // first prepare the request which will set up a NSLClientAsyncInfoPtr for us
  244.     iErr = NSLPrepareRequest( NULL, NULL, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo );
  245.  
  246.     if ( iErr.theErr )
  247.     {
  248.         printf("NSLPrepareRequest returned error %ld\r", iErr.theErr );
  249.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  250.         printf("Error: %s\r", gErrorString );
  251.         printf("Solution: %s\r", gSolutionString );
  252.     }
  253.         
  254.     // set the values of ourAsyncInfo pb
  255.     ourAsyncInfo->clientContextPtr = NULL;
  256.     ourAsyncInfo->maxSearchTime = 0;        // no max search time
  257.     ourAsyncInfo->alertInterval = 0;         // no alert interval
  258.     ourAsyncInfo->alertThreshold = 1;        // make alert threshold every item...
  259.  
  260.     if ( iErr.theErr == noErr )
  261.         iErr = NSLStartNeighborhoodLookup( ourRequestRef, neighborhood, ourAsyncInfo );
  262.     
  263.     do {
  264.         if ( iErr.theErr == noErr && ourAsyncInfo->totalItems > 0 )
  265.         {
  266.             while ( NSLGetNextNeighborhood( ourAsyncInfo, &nhPtr, &nhLength ) )
  267.             {        
  268.                 if ( nhLength > 0 && nhLength < kBufferLength  )
  269.                 {
  270.                     NSLGetNameFromNeighborhood( nhPtr, &tempPtr, &tempPtrLength );
  271.                     memcpy( tempName, tempPtr, tempPtrLength );
  272.                     tempName[tempPtrLength] = '\0';
  273.  
  274.                     printf( "%s\r", tempName );
  275.                 }
  276.             }
  277.         }
  278.         
  279.         if ( ourAsyncInfo->searchState == kNSLSearchStateComplete )
  280.             done = true;
  281.         else if ( iErr.theErr == noErr )
  282.             iErr = NSLContinueLookup( ourAsyncInfo );
  283.         
  284.     } while ( !iErr.theErr && !done );
  285.     
  286.     if ( iErr.theErr )
  287.     {
  288.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  289.         printf("Error: %s\r", gErrorString );
  290.         printf("Solution: %s\r", gSolutionString );
  291.     }    
  292.     
  293.     if ( buffer )
  294.         DisposePtr(buffer);
  295. }
  296.  
  297. void TestSyncServicesLookup( char* service )
  298. {
  299.     char                name[256] = "\p";
  300.     char                url[1024];
  301.     long                bufLen = kBufferLength;
  302.     char*                buffer = NewPtr( bufLen );
  303.     NSLRequestRef        ourRequestRef;
  304.     NSLClientAsyncInfoPtr    ourAsyncInfo;
  305.     NSLError            iErr = kNSLErrorNoErr;
  306.     NSLServicesList        serviceList = NULL;
  307.     NSLTypedDataPtr         newDataPtr = NULL;
  308.     NSLNeighborhood        neighborhood, urlPtr = NULL;
  309.     long                urlLength;
  310.     Boolean                done = false;
  311.     char                c;
  312.     
  313.     printf( "Please Type in the neighborhood you want to search then hit return\r" );
  314.     scanf("%c", &c );
  315.     
  316.     while ( c != '\r' && c != '\n' && name[0] < 256 )
  317.     {
  318.         name[0]++;
  319.         name[name[0]] = c;
  320.         scanf("%c", &c );
  321.     };
  322.     
  323.     p2cstr( (unsigned char*)name );
  324.     
  325.     neighborhood = NSLMakeNewNeighborhood( name, NULL );
  326.     printf( "Looking up Service\r\r" );
  327.     
  328.     // first prepare the request which will set up a NSLClientAsyncInfoPtr for us
  329.     iErr = NSLPrepareRequest( NULL, NULL, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo );
  330.  
  331.     if ( iErr.theErr )
  332.     {
  333.         printf("NSLPrepareRequest returned error %ld\r", iErr.theErr );
  334.  
  335.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  336.         printf("Error #%ld: %s\r", iErr.theErr, gErrorString );
  337.         printf("Solution: %s\r", gSolutionString );
  338.     }
  339.     else
  340.     {
  341.         serviceList = NSLMakeNewServicesList( service );    // we can pass a comma delimited cstring here (ie "http,ftp")
  342.         
  343.         // now we need to create a NSLTypedDataPtr which holds teh serviceList info as well as an attribute if we wish
  344.         if ( serviceList != NULL )
  345.         {
  346.             iErr.theErr = NSLMakeServicesRequestPB( serviceList, &newDataPtr );    // we can also pass an attribute if we want to get more specific
  347.             NSLDisposeServicesList( serviceList );                            // we are done with this, free this memory!        
  348.         }
  349.         
  350.         // set the values of ourAsyncInfo pb
  351.         ourAsyncInfo->clientContextPtr = NULL;
  352.         ourAsyncInfo->maxSearchTime = 0;        // no max search time
  353.         ourAsyncInfo->alertInterval = 0;         // no alert interval
  354.         ourAsyncInfo->alertThreshold = 1;        // make alert threshold every item...
  355.  
  356.         if ( iErr.theErr == noErr )
  357.             iErr = NSLStartServicesLookup( ourRequestRef, neighborhood, newDataPtr, ourAsyncInfo );
  358.  
  359.         do {
  360.             if ( iErr.theErr == noErr && ourAsyncInfo->totalItems > 0 )
  361.             {
  362.                 while ( NSLGetNextUrl( ourAsyncInfo, &urlPtr, &urlLength ) )
  363.                 {        
  364.                     if ( urlLength > 0 )
  365.                     {
  366.                         memcpy( url, urlPtr, urlLength );
  367.                         url[urlLength] = '\0';
  368.                         printf( "%s\r", url );
  369.                     }
  370.                 }
  371.             }
  372.             else if ( iErr.theErr )
  373.             {
  374.                 NSLErrorToString( iErr, gErrorString, gSolutionString );
  375.                 printf("Error #%ld: %s\r", iErr.theErr, gErrorString );
  376.                 printf("Solution: %s\r", gSolutionString );
  377.             }
  378.                     
  379.             if ( ourAsyncInfo->searchState == kNSLSearchStateComplete )
  380.                 done = true;
  381.             else
  382.                 iErr = NSLContinueLookup( ourAsyncInfo );    // if search state isn't complete, then the error wasn't fatal
  383.  
  384.         } while ( !done );                                    // it is possible to get errors back, but if the search state isn't complete, then one or more
  385.                                                             // plugins are still working!
  386.  
  387.         NSLFreeTypedDataPtr( newDataPtr );                    // dispose this
  388.     }
  389.     
  390.     NSLFreeNeighborhood( neighborhood );                    // make sure we free up this memory
  391.     
  392.     if ( buffer )
  393.         DisposePtr(buffer);
  394. }
  395.  
  396. typedef struct {
  397.     NSLRequestRef            theRequestRef;
  398.     NSLTypedDataPtr            theRequestDataPtr;
  399.     Boolean                    lookupFinished;
  400. } LookupContext, *LookupContextPtr;
  401.  
  402. pascal void ServicesLookupNotifyProc( NSLClientAsyncInfoPtr nslInfoPtr );
  403. pascal void ServicesLookupNotifyProc( NSLClientAsyncInfoPtr nslInfoPtr )
  404. {
  405.     LookupContextPtr    lookupContext = (LookupContextPtr)nslInfoPtr->clientContextPtr;
  406.     char*                curURL;
  407.     char*                urlPtr = NULL;
  408.     NSLError            nslError;
  409.     long                urlLength;
  410.     Boolean                weDone = false, cancelSearch = false;;
  411.     
  412.     // first check our ptrs and to see if this is from the current request
  413.     if ( nslInfoPtr && lookupContext )
  414.     {
  415.         // we might want to think about putting up an alert message here if we have received one...
  416.         if ( nslInfoPtr->searchResult.theErr )
  417.         {
  418.             if ( nslInfoPtr->searchState != kNSLSearchStateComplete )
  419.             {
  420.                 DoNSLNonFatalAlert( nslInfoPtr->searchResult, &cancelSearch );
  421.             }
  422.             else
  423.             {
  424.                 DoNSLFatalAlert( nslInfoPtr->searchResult );        // user has no choice
  425.                 cancelSearch = true;
  426.             }
  427.         }
  428.         
  429.         if ( nslInfoPtr->totalItems > 0 && !cancelSearch )
  430.         {
  431.             while ( NSLGetNextUrl( nslInfoPtr, &urlPtr, &urlLength ) )
  432.             {        
  433.                 if ( urlLength > 0 )
  434.                 {
  435.                     curURL = NewPtr( urlLength + 1 );                    // The NSL Manager WON'T call us at interrupt time so mem aloocation is OK!
  436.                     
  437.                     BlockMove( urlPtr, curURL, urlLength );
  438.                     curURL[urlLength] = '\0';                            // null terminate!
  439.                 }
  440.                 else
  441.                 {
  442.                     weDone = true;
  443.                 }
  444.                 
  445.                 if ( !weDone )
  446.                 {
  447.                     printf( "%s\r", curURL );
  448.                 }
  449.                 
  450.                 if ( curURL )
  451.                     DisposePtr( curURL );                                // now we could just have curURL be on the stack in this case but to show that 
  452.                                                                         // memory allocation is cool in the notifier we did it this way...
  453.                 
  454.                 curURL = NULL;
  455.             }
  456.         }
  457.     
  458.         if ( !cancelSearch && nslInfoPtr->searchState != kNSLSearchStateComplete )
  459.         {
  460.             nslError = NSLContinueLookup(nslInfoPtr);                    // don't forget to call NSLContinueLookup when you are done with the data in the buffer!
  461.             
  462.             if ( nslError.theErr )
  463.             {
  464.                 if ( nslInfoPtr->searchState != kNSLSearchStateComplete )
  465.                 {
  466.                     DoNSLNonFatalAlert( nslError, &cancelSearch );
  467.                 }
  468.                 else
  469.                 {
  470.                     DoNSLFatalAlert( nslError );        // user has no choice
  471.                     cancelSearch = true;
  472.                 }
  473.             }
  474.         }
  475.         
  476.         if ( !cancelSearch && nslInfoPtr->searchState == kNSLSearchStateComplete )
  477.         {
  478.             lookupContext->lookupFinished = true;
  479.             nslError = NSLDeleteRequest( lookupContext->theRequestRef );
  480.             
  481.             if ( nslError.theErr )
  482.                 DoNSLFatalAlert( nslError );        // user has no choice
  483.         }
  484.         else if ( cancelSearch )            // user decided error was bad enough to cancel the entire search
  485.         {
  486.             lookupContext->lookupFinished = true;
  487.             nslError = NSLCancelRequest( lookupContext->theRequestRef );
  488.             
  489.             if ( nslError.theErr == noErr )
  490.                 nslError = NSLDeleteRequest( lookupContext->theRequestRef );
  491.         }
  492.     }
  493. }
  494.  
  495.  
  496.  
  497. void TestAsyncServicesLookup( char* service )
  498. {
  499.     char                name[256] = "\p";
  500.     long                bufLen = kBufferLength;
  501.     char*                buffer = NewPtr( bufLen );
  502.     LookupContextPtr    contextPtr;
  503.     NSLRequestRef        ourRequestRef;
  504.     NSLClientAsyncInfoPtr    ourAsyncInfo;
  505.     NSLError            iErr = kNSLErrorNoErr;
  506.     NSLServicesList        serviceList = NULL;
  507.     NSLTypedDataPtr         newDataPtr = NULL;
  508.     NSLNeighborhood        neighborhood, urlPtr = NULL;
  509.     Boolean                done = false;
  510.     char                c;
  511.     
  512.     printf( "Please Type in the neighborhood you want to search then hit return\r" );
  513.     scanf("%c", &c );
  514.     
  515.     while ( c != '\r' && c != '\n' && name[0] < 256 )
  516.     {
  517.         name[0]++;
  518.         name[name[0]] = c;
  519.         scanf("%c", &c );
  520.     };
  521.     
  522.     p2cstr( (unsigned char*)name );
  523.     
  524.     neighborhood = NSLMakeNewNeighborhood( name, NULL );
  525.     printf( "Looking up Service\r\r" );
  526.     
  527.     // first prepare the request which will set up a NSLClientAsyncInfoPtr for us
  528.     contextPtr = NewPtr( sizeof( LookupContext ) );
  529.     if ( !contextPtr )
  530.     {
  531.         printf( "NewPtr call failed!" );
  532.         return;
  533.     }
  534.     
  535.     iErr = NSLPrepareRequest( ServicesLookupNotifyProc, contextPtr, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo );
  536.  
  537.     if ( iErr.theErr )
  538.     {
  539.         printf("NSLPrepareRequest returned error %ld\r", iErr.theErr );
  540.  
  541.         NSLErrorToString( iErr, gErrorString, gSolutionString );
  542.         printf("Error #%ld: %s\r", iErr.theErr, gErrorString );
  543.         printf("Solution: %s\r", gSolutionString );
  544.     }
  545.     else
  546.     {
  547.         contextPtr->theRequestRef = ourRequestRef;
  548.         contextPtr->theRequestDataPtr = ourAsyncInfo;
  549.         contextPtr->lookupFinished = false;
  550.         
  551.         serviceList = NSLMakeNewServicesList( service );    // we can pass a comma delimited cstring here (ie "http,ftp")
  552.         
  553.         // now we need to create a NSLTypedDataPtr which holds teh serviceList info as well as an attribute if we wish
  554.         if ( serviceList != NULL )
  555.         {
  556.             iErr.theErr = NSLMakeServicesRequestPB( serviceList, &newDataPtr );    // we can also pass an attribute if we want to get more specific
  557.             NSLDisposeServicesList( serviceList );                            // we are done with this, free this memory!        
  558.         }
  559.         
  560.         // set the values of ourAsyncInfo pb
  561.         ourAsyncInfo->maxSearchTime = 0;        // no max search time
  562.         ourAsyncInfo->alertInterval = 0;         // no alert interval
  563.         ourAsyncInfo->alertThreshold = 1;        // make alert threshold every item...
  564.  
  565.         if ( iErr.theErr == noErr )
  566.             iErr = NSLStartServicesLookup( ourRequestRef, neighborhood, newDataPtr, ourAsyncInfo );
  567.  
  568.         if ( iErr.theErr == noErr )
  569.         {
  570.             while ( !contextPtr->lookupFinished )
  571.             {
  572.                 YieldToAnyThread();                            // its important to have a call to YieldToAnyThread in your main event loop
  573.                                                             // which is what we are simulating here...
  574.                 SystemTask();
  575.             }
  576.         }
  577.         
  578.         NSLFreeTypedDataPtr( newDataPtr );                    // dispose this
  579.     }
  580.     
  581.     NSLFreeNeighborhood( neighborhood );                    // make sure we free up this memory
  582.     
  583.     if ( buffer )
  584.         DisposePtr(buffer);
  585. }
  586.  
  587.  
  588. // the code below is provided as an example, but won't work here because we don't have an event loop
  589. // that calls YieldToAnyThread.
  590. void TestStandardRegisterURL(void)
  591. {
  592.     char                url[1024];
  593.     UInt16                index = 0;
  594.     NSLError            regError;
  595.     char                c;
  596.     
  597.     printf( "Please Type in the url you want to register then hit return\r" );
  598.     scanf("%c", &c );
  599.     
  600.     while ( c != '\r' && c != '\n' && index < sizeof(url)-1 )
  601.     {
  602.         url[index++] = c;
  603.         scanf("%c", &c );
  604.     };
  605.     
  606.     url[index] = '\0';        // null terminate this
  607.     
  608.     regError = NSLStandardRegisterURL( url, nil );        // we aren't going to specify a neighborhood to register in, leave it up to the plugins
  609.     
  610.     if ( regError.theErr )
  611.     {
  612.         NSLErrorToString( regError, gErrorString, gSolutionString );
  613.         printf("Error #%ld: %s\r", regError.theErr, gErrorString );
  614.         printf("Solution: %s\r", gSolutionString );
  615.     }
  616.     else
  617.         printf("URL registered");
  618. }
  619.  
  620. void TestStandardDeregisterURL(void)
  621. {
  622.     char                url[1024];
  623.     UInt16                index = 0;
  624.     NSLError            regError;
  625.     char                c;
  626.     
  627.     printf( "Please Type in the url you want to register then hit return\r" );
  628.     scanf("%c", &c );
  629.     
  630.     while ( c != '\r' && c != '\n' && index < sizeof(url)-1 )
  631.     {
  632.         url[index++] = c;
  633.         scanf("%c", &c );
  634.     };
  635.     
  636.     url[index] = '\0';        // null terminate this
  637.     
  638.     regError = NSLStandardDeregisterURL( url, nil );        // we aren't going to specify a neighborhood to deregister in, leave it up to the plugins
  639.     
  640.     if ( regError.theErr )
  641.     {
  642.         NSLErrorToString( regError, gErrorString, gSolutionString );
  643.         printf("Error #%ld: %s\r", regError.theErr, gErrorString );
  644.         printf("Solution: %s\r", gSolutionString );
  645.     }
  646.     else
  647.         printf("URL deregistered");
  648. }
  649.  
  650.